﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using Common;
using country;
using Flag;
using Newtonsoft.Json;
using province;
using UnityEngine.UI;
using Color = UnityEngine.Color;
using Debug = UnityEngine.Debug;
using Object = System.Object;

[ExecuteInEditMode]
public class ProvinceGrid : MonoBehaviour {

    public Texture2D kProvinceMap;
    public RenderTexture kProvinceColorMap;

    public int kProvinceCount;
    public Material kLut;

    private Dictionary<Color, int> kProvinceColorToIDMap = new Dictionary<Color, int>();
    private Dictionary<string, CountryData> kCountryMetaMap = new Dictionary<string, CountryData>();

    private ProvinceData[] kProvinceMetas;
    private CountryData[] kCountryMetas;
    private Dictionary<int, ProvinceData> kProvinceMetaMap = new Dictionary<int, ProvinceData>();

    private Texture2D kProvincePolitimap;
    private SavingJson savingJson;
    private ProvinceData preData = new ProvinceData();
    
    public BorderCell kcell;
    // Use this for initialization
    private BorderCell[] cells;

    


    void Awake()
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
       // LoadFromJson();
        //SaveEachToJson();
        LoadFromBytes();
        SpecialChangeColor();
        if (Application.isPlaying) {
            InitBorder();
        }

        //SaveToBytes();
        stopwatch.Stop();
        Debug.Log("provinceGrid启动时间为：" + stopwatch.ElapsedMilliseconds);
    }

    void InitBorder()
    {
        cells = new BorderCell[5];
        for (int i = 0; i < 5; ++i)
        {
            var objtar = kcell.gameObject;
            var transformcache = this.transform;
            var ins = GameObject.Instantiate(objtar, transformcache);

            var cell = ins.GetComponent<BorderCell>();
            ins.name = objtar.name + string.Format("_{0}",i+1);
            cells[i] = cell;
            cell.gen(i);
        }
    }
    
    public void SaveToBytes()
    {
        SaveingBytes saveingBytes = new SaveingBytes(kProvinceMetas, kCountryMetas);

        //开始序列化
        FileStream fileStream = new FileStream(Application.streamingAssetsPath
                                               + "/temp/save.bin", FileMode.Create);
        var bytes = Serializer.Serialize(saveingBytes);
        BinaryWriter writer = new BinaryWriter(fileStream);
        writer.Write(bytes);
        writer.Close();
        fileStream.Close();
    }
    
    public void LoadFromBytes()
    {
        Stopwatch stopwatch = Stopwatch.StartNew();
        stopwatch.Start();
        FileStream fileStream = new FileStream(Application.streamingAssetsPath
                                               + "/temp/save.bin", FileMode.Open);
        BinaryReader reader = new BinaryReader(fileStream);
        var bytes = Helper.ReadAllBytes(reader);
        var tempJson = Serializer.Deserialize<SaveingBytes>(bytes);
        
        kCountryMetas = tempJson.CountryMetas.ToArray();
        kProvinceMetas = tempJson.ProvinceMetas.ToArray();
        kProvinceCount = kProvinceMetas.Length;
        foreach (var meta in kCountryMetas)
        {
            meta.InitFromBytes();
            kCountryMetaMap.Add(meta.tag,meta);
        }
        
        foreach (var meta in kProvinceMetas)
        {
            meta.InitFromBytes();
            kProvinceMetaMap.Add(meta.Id,meta);

            kProvinceColorToIDMap.Add(meta.kMapColor, meta.Id);
            
            if (kCountryMetaMap.ContainsKey(meta.owner))
            {
                if(meta.owner.Equals("TER") || meta.owner.Equals("NON"))
                    continue;
                meta.kShowColor = kCountryMetaMap[meta.owner].color;
                ChangeTargetProvinceColor(meta.kMapColor,meta.kShowColor);
            }

        }
        reader.Close();
    }
    public void InitCountries()
    {
        kCountryMetas = new CountryData[ConfigParam.MAXCountryCount];
        var dirPath = Application.streamingAssetsPath + "/temp/countries/";
        var directoryInfo_ = new DirectoryInfo(dirPath);
        int i = 0;
        foreach (var fileInfo in directoryInfo_.GetFiles())
        {
            if (Path.GetExtension(fileInfo.Name) == ".meta") continue;
            try
            {
                StreamReader reader = new StreamReader(dirPath + fileInfo.Name);
                var temp_name = fileInfo.Name.Replace(" - ", "-");
                var ss = temp_name.Split(new char[] {'-'}, StringSplitOptions.RemoveEmptyEntries);
                var tag = ss[0];
                var context = reader.ReadToEnd();
                var meta = JsonConvert.DeserializeObject<CountryData>(context);
                meta.InitFromJson();
                kCountryMetaMap.Add(tag,meta);
                kCountryMetas[i++] = meta;
            }
            catch (JsonReaderException)
            {
                Debug.Log("出问题的是"+fileInfo.Name);
            }
        }
    }


    private void InitProvinces()
    {
        kProvinceMetas = new ProvinceData[ConfigParam.MAXProvinceCount];    
        var dirPath = Application.streamingAssetsPath + "/temp/provinces/";
        var directoryInfo_ = new DirectoryInfo(dirPath);
        int count = 0;
        foreach (var fileInfo in directoryInfo_.GetFiles())
        {
            if (Path.GetExtension(fileInfo.Name) == ".meta") continue;
            try
            {
                StreamReader reader = new StreamReader(dirPath + fileInfo.Name);
                var context = reader.ReadToEnd();
                var meta = JsonConvert.DeserializeObject<ProvinceData>(context);
                meta.InitFromJson();
                reader.Close();
                if (!kProvinceColorToIDMap.ContainsKey(meta.kMapColor))
                {
                    kProvinceColorToIDMap.Add(meta.kMapColor, meta.Id);
                }

                if (kCountryMetaMap.ContainsKey(meta.owner))
                {
                    meta.kShowColor = kCountryMetaMap[meta.owner].color;
                    ChangeTargetProvinceColor(meta.kMapColor,meta.kShowColor);
                }
                kProvinceMetas[count++] = meta;
            }
            catch (JsonReaderException)
            {
                Debug.Log("出问题的是"+fileInfo.Name);
            }
        }

        kProvincePolitimap = new Texture2D(ConfigParam.BLOCKMAXWIDTH, ConfigParam.BLOCKMAXHEIGHT);
        Graphics.ConvertTexture(kProvinceMap, kProvincePolitimap);
        kProvinceCount = count;
    }
    public int GetProvinceID( int x, int z)
    {
        x = x % kProvinceMap.width;
        z = z % kProvinceMap.height;

        var col = kProvinceMap.GetPixel(x, z);
        int ID = -1;

        if( kProvinceColorToIDMap.TryGetValue(col, out ID))
        {

        }

        return ID;
    }

    public int GetProvinceID( Color col)
    {
        int ID = -1;
        kProvinceColorToIDMap.TryGetValue(col, out ID);
        return ID;
    }

    public ProvinceData GetProvinceData( int x, int z)
    {
        return GetProvinceData(GetProvinceID(x, z));
    }

    public ProvinceData GetProvinceData( int ID)
    {
        if( ID <0 || ID >= kProvinceMetas.Length)
        {
            return null;
        }
        return kProvinceMetas[ID];

    }

    public ProvinceData GetProvinceData( Color col)
    {
        return GetProvinceData(GetProvinceID(col));
    }

    public void ChangeProvinceColor()
    {
        var width = kProvinceMap.width;
        var height = kProvinceMap.height;

        LC_Helper.Loop(width, (i) =>
        {
            LC_Helper.Loop(height, (j) =>
            {
                var col = kProvinceMap.GetPixel(i, j);
                var pdata = GetProvinceData(col);

                if(pdata != null)
                {
                    kProvincePolitimap.SetPixel(i, j, pdata.kShowColor);
                }

            });

        });

        kProvincePolitimap.Apply();

        Graphics.Blit(kProvincePolitimap, kProvinceColorMap);
    }

    public void ChangeTargetProvinceColor(Color kBaseColor, Color kTargeColor)
    {
        kLut.SetColor("_BaseColor", kBaseColor);
        kLut.SetColor("_TarColor", kTargeColor);
        kLut.SetTexture("_MainTex", kProvinceColorMap);

        Graphics.Blit(kProvinceColorMap, kProvinceColorMap, kLut);
    }
    
    public void RayTest()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction, Color.red);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, int.MaxValue, 1 << LayerMask.NameToLayer("Terrain")))
        {
            Debug.Log("检测到物体" + hit.point);
            //Pickat(hit.point);
            PickEx(hit.point);
        }
        
    }

    public void FixedUpdate()
    {
        if (Input.GetMouseButtonUp(0))
        {
            RayTest();
        }
    }
    
        public void PickEx(Vector3 pos)
        { 
            var id = GetProvinceID((int) pos.x, (int) pos.z);
            if (kProvinceMetaMap.ContainsKey(id))
            {
                var meta = kProvinceMetaMap[id];
                var pre_owner = preData.owner;
                preData = meta;
                Debug.Log(String.Format("选择到省份{0},所属国家为{1}",id,kProvinceMetaMap[id].owner) );
                if(meta.owner.Equals("TER") || meta.owner.Equals("NON")) return;
                if(pre_owner == meta.owner) return;
                GameObject.Find("CountryFlag").GetComponent<GameFlag>().setImage(meta.owner);
            }
            else
            {
                Debug.Log(String.Format("选择到省份{0},该省份尚未定义",id) );
            }
            /*
            var Pdata = GetProvinceData(id);
            if (Pdata != null)
            {
                var col = kProvinceMap.GetPixel((int)pos.x, (int)pos.z);
                var tarcol = Color.white;
                if (Pdata.kShowColor.a > 0.5)
                {
                    tarcol = Color.yellow;
                    tarcol.a = 0;
                }
                else
                {
                    tarcol = Color.red;
                    tarcol.a = 1;
                }
                Pdata.kShowColor = tarcol;
                ChangeTargetProvinceColor(col, tarcol);
                /*
                var border_col = Color.blue;
                border_col.a = 1;
                List<Border> borders;
                borderMap.TryGetValue(id, out borders);
                foreach (var border in borders)
                {
                    foreach (var point in border.pointList)
                    {
                        kProvincePolitimap.SetPixel(point.x,point.y,border_col);
                    }
                }
                kProvincePolitimap.Apply();
                
                Graphics.Blit(kProvincePolitimap, kProvinceColorMap);
                }
            */
            
    }


    public void Pickat(Vector3 pos)
    {
        Debug.Log("选择到省份" + GetProvinceID((int)pos.x, (int)pos.z));

        var Pdata = GetProvinceData((int)pos.x, (int)pos.z);
        if(Pdata != null)
        {
            if(Pdata.kShowColor.a > 0.5)
            {
                Pdata.kShowColor = Color.black;
                Pdata.kShowColor.a = 0;
            }
            else
            {
                Pdata.kShowColor = Color.blue;
                Pdata.kShowColor.a = 1;
            }

            ChangeProvinceColor();
        }
    }
    
    private void SpecialChangeColor()
    {
        Special_ChangeColor(4154,197);
        Special_ChangeColor(4162,1869);
        Special_ChangeColor(4160,1873);
        Special_ChangeColor(4161,1871);
        Special_ChangeColor(4159,1768);
        Special_ChangeColor(4146,23);
        Special_ChangeColor(4153,21);
        Special_ChangeColor(4155,158);
        Special_ChangeColor(4169,340);
        Special_ChangeColor(4168,349);
        Special_ChangeColor(4167,2467);
        Special_ChangeColor(4569,344);
        Special_ChangeColor(4156,2197);
        Special_ChangeColor(4179,2307);
        Special_ChangeColor(4172,2212);
        Special_ChangeColor(4177,2216);
        Special_ChangeColor(4170,2210);
        Special_ChangeColor(4328,434);
        Special_ChangeColor(2200,577);
        Special_ChangeColor(1787,2128);
        Special_ChangeColor(1785,2127);
        Special_ChangeColor(1786,712);
        Special_ChangeColor(1784,712);
        Special_ChangeColor(4403,4212);
        Special_ChangeColor(2194,708);
        Special_ChangeColor(4657,4201);
        Special_ChangeColor(4402,2395);
        Special_ChangeColor(4400,570);
        Special_ChangeColor(1950,570);
        Special_ChangeColor(4401,579);
        Special_ChangeColor(1795,2326);
        Special_ChangeColor(2334,393);
        Special_ChangeColor(4276,2336);
        Special_ChangeColor(4321,360);
        Special_ChangeColor(4322,360);
        Special_ChangeColor(1229,2323);
        Special_ChangeColor(1794,2460);
        Special_ChangeColor(2129,4518);
        Special_ChangeColor(1788,4517);
        Special_ChangeColor(4178,329);
        Special_ChangeColor(1793,348);
        Special_ChangeColor(4157,205);
        Special_ChangeColor(1779,2339);

    }

    private void Special_ChangeColor(int x,int y)
    {
        kProvinceMetaMap[x].kShowColor = kProvinceMetaMap[y].kShowColor;
        ChangeTargetProvinceColor(kProvinceMetaMap[x].kMapColor,kProvinceMetaMap[x].kShowColor);
    }

    
    
    
}
